#include <string.h>
#include <time.h>
#include <unistd.h>

#include <libxml/tree.h>
#include <xmlsec/xmltree.h>

#include "mcx.h"

const char ns_mcxws[] = "urn:doshwsdl";
const char ns_mcx[] = "urn:dosh";

GHashTable *mcx_balance(xmlSecKeyPtr key) {
  xmlDocPtr balance, response;

  balance = mcx_balance_request(key);
  response = mcx_send("BalanceService", balance);
  return mcx_balanceStatus_parse(response);
}

GHashTable *mcx_balanceStatus_parse(xmlDocPtr doc) {
  GHashTable *ret;
  xmlNodePtr root, list, ptr;

  if(!doc || !(root = xmlDocGetRootElement(doc)) ||
     !xmlSecCheckNodeName(root, "balanceStatus", ns_mcxws))
    return NULL;
  ret = g_hash_table_new(g_str_hash, g_str_equal);
  if((list = xmlSecFindChild(root, "amountList", ns_mcx)))
    for(ptr = list->children; ptr; ptr = ptr->next)
      if(xmlSecCheckNodeName(ptr, "amount", ns_mcx))
	g_hash_table_insert(ret,
			    xmlGetProp(ptr, "currency"),
			    xmlNodeGetContent(ptr));
  return ret;
}

xmlDocPtr mcx_balance_request(xmlSecKeyPtr key) {
  xmlDocPtr balance;
  xmlNodePtr root, e, sig;
  xmlNsPtr dosh;
  char *tmp;
  
  if(!key)
    return NULL;

  balance = mcx_doc_new(ns_mcxws, "mcxws", "balanceRequest", NULL, &root);
  dosh = xmlNewNs(root, ns_mcx, "mcx");

  /* validityInterval */
  e = xmlNewDocNode(balance, dosh, "validityInterval", NULL);
  tmp = mcx_time(time(NULL));
  tmp[strlen(tmp) - 6] = 'Z';
  tmp[strlen(tmp) - 5] = 0;
  xmlAddChild(e, xmlNewDocNode(balance, dosh, "notBefore", tmp));
  tmp = mcx_time(time(NULL) + 60);
  tmp[strlen(tmp) - 6] = 'Z';
  tmp[strlen(tmp) - 5] = 0;
  xmlAddChild(e, xmlNewDocNode(balance, dosh, "notAfter", tmp));
  xmlAddChild(root, e);

  sig = mcx_sign(root, key);
  if(!sig)
    return NULL;

  return balance;
}
